home *** CD-ROM | disk | FTP | other *** search
/ Aminet 32 / Aminet 32 (1999)(Schatztruhe)[!][Aug 1999].iso / Aminet / comm / tcp / Socks5.lha / Socks5 / src / server / sema.c < prev    next >
C/C++ Source or Header  |  1999-03-10  |  5KB  |  186 lines

  1. /* Copyright (c) 1995-1999 NEC USA, Inc.  All rights reserved.               */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6.  
  7. /*
  8.  * $Id: sema.c,v 1.20.4.3 1999/02/03 22:35:42 steve Exp $
  9.  */
  10.  
  11. #include "socks5p.h"
  12. #include "sema.h"
  13. #include "log.h"
  14.  
  15. #ifdef USE_SYSTEM_SEMAPHORE
  16. #ifdef HAVE_SYS_IPC_H
  17. #include <sys/ipc.h>
  18. #endif
  19.  
  20. #ifdef HAVE_SYS_SEM_H
  21. #include <sys/sem.h>
  22. #endif
  23.  
  24. #ifndef HAVE_UNION_SEMUN
  25. union semun { int val; struct semid_ds *buf; u_short *array; };
  26. #endif
  27.  
  28. int semacquire(void *sem) {
  29.     struct sembuf sb = { 0, -1, SEM_UNDO };
  30.  
  31.     if (sem && semop(*(int *)sem, &sb, 1) < 0) {
  32.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semacquire: semop failed: %m");
  33.     return -1;
  34.     }
  35.  
  36.     return 0;
  37. }
  38.  
  39. int semrelease(void *sem) {
  40.     struct sembuf sb = { 0, 1, SEM_UNDO };
  41.  
  42.     if (sem && semop(*(int *)sem, &sb, 1) < 0) {
  43.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semrelease: semop failed: %m");
  44.     return -1;
  45.     }
  46.  
  47.     return 0;
  48. }
  49.  
  50. int semreset(void *sem, int val) {
  51.     /* I think semaphores with UNDO won't need resetting...                  */
  52.     return 0;
  53. }
  54.  
  55. void semdestroy(void *sem) {
  56.     union semun u;
  57.     u.val = 1;
  58.  
  59.     semctl(*(int *)sem, 0, IPC_RMID, u);
  60. }
  61.  
  62. void *semcreate(int val) {
  63.     int *semid = (int *)malloc(sizeof(int));
  64.     union semun u;
  65.  
  66.     u.val = val;
  67.  
  68.     if (semid == NULL) {
  69.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: malloc failed");
  70.     return NULL;
  71.     }
  72.  
  73.     if ((*semid = semget(IPC_PRIVATE, 1, 0666)) < 0) {
  74.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: semget failed: %m");
  75.     return NULL;
  76.     }
  77.  
  78.     if (semctl(*semid, 0, SETVAL, u) < 0) {
  79.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: semctl failed: %m");
  80.     return NULL;
  81.     }
  82.  
  83.     return (void *)semid;
  84. }
  85. #elif defined(USE_SEMAPHORES)
  86.  
  87. #ifdef HAVE_SYS_IOCTL_H
  88. #include <sys/ioctl.h>
  89. #endif
  90. #ifdef HAVE_SYS_FILIO_H
  91. #include <sys/filio.h>
  92. #endif
  93.  
  94. static int semstart(S5IOHandle *fd, int count) {
  95.     if (pipe(fd) < 0) {
  96.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semstart: pipe failed: %m");
  97.     return -1;
  98.     }
  99.     
  100.     while (count-- > 0) semrelease((void *)fd);
  101.     return 0;
  102. }
  103.  
  104. /* Lock (using the semaphore pipe, semfd) control of the signaling and pipes */
  105. /* (pipe reads and writes are atomic, so the pipe can act as a semaphore.)   */
  106. int semacquire(void *sem) {
  107.     S5IOHandle *fd = (int *)sem;
  108.     char c;
  109.  
  110.     if (sem && RECVSOCKET(fd[0], &c, 1, 0) < 0) {
  111.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semacquire: read failed: %m");
  112.     return -1;
  113.     }
  114.  
  115.     return 0;
  116. }
  117.  
  118. /* Unlock (using the semaphore pipe) control of the signaling and pipes      */
  119. /* (pipe reads and writes are atomic, so the pipe can act as a semaphore.)   */
  120. int semrelease(void *sem) {
  121.     S5IOHandle *fd = (int *)sem;
  122.  
  123.     if (sem && SENDSOCKET(fd[1], " ", 1, 0) != 1) {
  124.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semrelease: write failed: %m");
  125.     return -1;
  126.     }
  127.  
  128.     return 0;
  129. }
  130.  
  131. int semreset(void *sem, int val) {
  132.     S5IOHandle *fd = (int *)sem;
  133.     int nq;
  134.  
  135.     /* ok? */
  136.     if (sem == NULL) return 0;
  137.  
  138. #ifdef FIONREAD
  139.     ioctl(fd[0], FIONREAD, (char *)&nq);
  140.     if (nq == val) return 0;
  141. #else
  142.     /* on some OSs fstat works on pipes, if it doesn't, it will return -1,   */
  143.     /* and we'll be ok.                                                      */
  144.     {
  145.       struct stat sb;
  146.       if (fstat(fd[0], &sb) == 0 && sb.st_size == val) return 0;
  147.     }
  148. #endif
  149.  
  150.     /* Need to reset it, really...                                           */
  151.     close(fd[0]);
  152.     close(fd[1]);
  153.  
  154.     return semstart((int *)sem, val);
  155.  
  156.     /* Since this only gets called on HUPs, we can deal with recreating the  */
  157.     /* pipe -- It doesn't happen that often, and the old pipe should be      */
  158.     /* gone or will be as soon as the last child that has it open exits.     */
  159.  
  160.     /* while (nq-- > val) semacquire(sem); while (nq++ < val)                */
  161.     /* semrelease(sem);                                                      */
  162. }
  163.  
  164. void semdestroy(void *sem) {
  165.     S5IOHandle *fd = (int *)sem;
  166.  
  167.     if (!sem) return;
  168.     close(fd[0]);
  169.     close(fd[1]);
  170.     free(sem);
  171. }
  172.  
  173. void *semcreate(int count) {
  174.     S5IOHandle *fd;
  175.  
  176.     if ((fd  = (int *)malloc(2 * sizeof(int)))== NULL) {
  177.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(0), 0, "Semcreate: malloc failed");
  178.     return NULL;
  179.     }
  180.  
  181.     semstart(fd, count);
  182.     return (void *)fd;
  183. }
  184.  
  185. #endif /* not __svr4__ */
  186.